home *** CD-ROM | disk | FTP | other *** search
/ Precision Software Appli…tions Silver Collection 1 / Precision Software Applications Silver Collection Volume One (PSM) (1993).iso / demos / devel3.exe / DEVEL3.DOC < prev    next >
Text File  |  1992-06-08  |  43KB  |  968 lines

  1.  
  2.       REND386 -- A 3-D Polygon Rendering Package for the 386 and 486
  3.                   Written by Dave Stampe and Bernie Roehl
  4.  
  5.                            LIBRARY Documentation
  6.                          Version 3.01 - June 1992
  7.  
  8. This package contains a library of routines (callable from C) that will
  9. render 3 dimensional scenes on 386 and 486 based systems with a VGA display.
  10.  
  11. The package also includes a simple user-interface library with joystick
  12. support, and a demo program to show what it's capabable of.
  13.  
  14. The package is designed to be fast.   It accomplishes that goal by making
  15. use of the special instructions that exist only on 386 and 486 processors;
  16. it will not run on 286s, 8086s or 8088s.
  17.  
  18. It also requires Turbo C++ or Borland C to link; Turbo C 2.00 seems to
  19. generate unresolved references.
  20.  
  21. A NOTE ON SPEED:
  22.  
  23. Speed is not a straightforward thing to measure.  There is a relationship
  24. between the speed of the processor, the complexity of the scene, and the
  25. number of frames per second.
  26.  
  27. With this software, a 512-polygon scene can be rendered at speeds up to
  28. 14 frames/second on a 486/25; this corresponds to a speed of over 7000
  29. polys/second.
  30.  
  31. LICENSING:
  32.  
  33. These libraries may be freely used to write software for release into the
  34. public domain.  Permission to use these libraries for the production of
  35. commercial software (including shareware) must be obtained from the authors,
  36. Bernie Roehl (broehl@sunee.uwaterloo.ca) and Dave Stampe
  37. (dstampe@sunee.uwaterloo.ca).
  38.  
  39. Licensing terms will be very, very reasonable.
  40.  
  41. SOFTWARE DOCUMENTATION
  42.  
  43. The following sessions describe the various data structures and routines
  44. that comprise the rend386 package.
  45.  
  46. SECTION A -- OBJECTS
  47.  
  48. The following functions deal with OBJECTs.  OBJECTs have several properties
  49. associated with them: a set of vertices, a set of polygons, a name, an
  50. owner and a set of flags.  Each vertex has an x,y,z location in the object's
  51. native coordinates, and a (probably different) x,y,z location in world
  52. coordinates.  Each polygon has a color value and an array of pointers to the
  53. vertices that define that polygon.
  54.  
  55. OBJECT *new_obj(int type, int nv, int np, char *name)
  56.          Creates a new object, with room for up to nv vertices and np polygons.
  57.          The given name is set in the object.
  58.  
  59. void add_vertex(OBJECT *obj, long x, long y, long z)
  60.          Adds a vertex to the given object, with x,y,z as its coordinates
  61.          in object space.
  62.  
  63. POLY *add_poly(OBJECT *obj, unsigned color, int npoints)
  64.          Adds a polygon to the given object, with the given color and room
  65.          for up to npoints vertices.
  66.  
  67. void add_point(OBJECT *obj, POLY *p, int vertnum)
  68.          Adds a point to a polygon.  Vertex number vertnum in object obj is
  69.          added to the given polygon.  The vertices must be added in a
  70.          "clockwise" order as seen from outside the object.
  71.  
  72. void delete_obj(OBJECT *obj)
  73.          Deletes the given object and frees all memory associated with it.
  74.  
  75. long object_bounds(OBJECT *obj, long *x, long *y, long *z)
  76.          Obtains the x,y,z extents of the given object.
  77.  
  78. void compute_obj(OBJECT *obj)
  79.          Does internal computation of polygon normals, bounding sphere, and
  80.          so forth.  Must be called once the object is complete (i.e. all the
  81.          vertices and polygons have been added, and the points comprising
  82.          the polys have been defined) and before the object is rendered.
  83.  
  84. unsigned get_object_sorting(OBJECT *ojb)
  85.          Returns the current value of the object's depth sorting type field.
  86.          Values are:
  87.              DEEPEST - the default; sorts by deepest (i.e. farthest) vertex
  88.              AVERAGE - use average depth rather than maximum
  89.              ATBACK  - sorts the polys as if they were very far away
  90.          You can also depth sort by object rather than by poly by OR'ing in
  91.          the BYOBJECT value.  In addition, you can sort by the object's
  92.          clipping sphere by OR'ing in the USE_CENTER value.
  93.  
  94. void set_object_sorting(OBJECT *obj, unsigned depth_type)
  95.          Sets an object's depth sorting type field.
  96.  
  97. void set_obj_flags(OBJECT *obj, unsigned char value)
  98.          Sets the object's flags.
  99.  
  100. unsigned char get_obj_flags(OBJECT *obj)
  101.          Gets the object flags.
  102.  
  103. The bottom two bits of the flags word are named OBJ_INVIS (which indicates
  104. that the object is invisible and should not be drawn) and OBJ_HIGHLIGHTED
  105. (indicating that the object should be drawn highlighted).
  106.  
  107. void get_obj_info(OBJECT *obj, int *nv, int *np, char *buffer, int maxn)
  108.         Extracts the number of vertices in obj and stores it in *nv, and
  109.         similarly stores the number of polys in obj in *np.  If maxn is
  110.         non-zero, the given buffer is filled in with the name of the object
  111.         (if one has been set).  The buffer must contain room for up to maxn
  112.         characters.
  113.  
  114. void get_vertex_info(OBJECT *obj, int vertnum, long *x, long *y, long *z)
  115.         Extracts the x, y and z values of vertex number vertnum in obj.
  116.         This function obtains the coordinates in the object coordinate system.
  117.  
  118. void get_vertex_world_info(OBJECT *obj, int vertnum, long *x, long *y, long *z)
  119.         Extracts the x, y and z values of vertex number vertnum in obj.
  120.         This function obtains the coordinates in the world coordinate system.
  121.  
  122. void get_poly_info(OBJECT *obj, int polynum, unsigned *color, int *nverts,
  123.    int *verts, int maxverts)
  124.         Extracts information from polygon number polynum in obj.  The color
  125.         parameter is set to the polygon color (see colors.doc for details).
  126.         If maxverts is non-zero, then the array of integers verts is filled
  127.         in with the index numbers of the vertices comprising the polygon.
  128.         No more than maxverts vertices will be stored; if there are more
  129.         than that number of vertices in the object, the rest will be ignored.
  130.  
  131. void set_poly_color(OBJECT *obj, int polynum, unsigned color)
  132.         Sets the color of polygon number polynum in obj to the given color.
  133.         See colors.doc for details of how the color parameter is interpreted.
  134.  
  135. void *get_object_owner(OBJECT *obj)
  136.         Returns the owner field of the given object.  The owner field is not
  137.         used by the renderer, and is provided for the convenience of the
  138.         application programmer.  It might, for example, be a pointer to the
  139.         segment that this object is the representation of (see the section on
  140.         segments for more information).
  141.  
  142. void set_object_owner(OBJECT *obj, void *owner)
  143.         Sets the object's owner field.
  144.  
  145. OBJECT *copy_obj(OBJECT *obj, int nverts, int npolys, char *name)
  146.         Makes a copy of the given object, with room for nverts vertices and
  147.         npolys polygons.  This is to allow you to add additional vertices
  148.         and polygons using an existing object as a starting point.  The name
  149.         field is set in the copy.
  150.  
  151. void copy_world_to_object(OBJECT *obj)
  152.         Copies the world coordinates of the object into its object coordinates,
  153.         effectively making the object's coordinate system the same as the
  154.         world coordinate system.  Rarely used.
  155.  
  156. void highlight_obj(OBJECT *obj)
  157.         Turns on the HIGHLIGHT bit in the color field of all the polys in the
  158.         given object.
  159.  
  160. void unhighlight_obj(OBJECT *obj)
  161.         Turns off the HIGHLIGHT bit in the color field of all the polys in the
  162.         given object.
  163.  
  164. SECTION B -- OBJLISTS
  165.  
  166. The following functions deal with object lists, or OBJLISTs.  An OBJLIST is
  167. what you pass to the renderer (i.e. you tell it to render a given list of
  168. objects).
  169.  
  170. OBJLIST *new_objlist()
  171.         Creates a new object list and returns a pointer to it.
  172.  
  173. void add_to_objlist(OBJLIST *list, OBJECT *obj)
  174.         Adds an object to an object list.
  175.  
  176. void remove_from_objlist(OBJLIST *list, OBJECT *obj)
  177.         Removes an object from an object list.
  178.  
  179. void del_objlist(OBJLIST *list)
  180.         Deletes an object list.
  181.  
  182. OBJECT *first_in_objlist(OBJECT **objlist)
  183.         Returns a pointer to the first object in a list.
  184.  
  185. OBJECT *next_in_objlist(OBJECT **objlist, OBJECT *obj)
  186.         Returns a pointer to the next object (after obj) in a list.
  187.  
  188. OBJECT *prev_in_objlist(OBJECT **objlist, OBJECT *obj)
  189.         Returns a pointer to the previous object (after obj) in a list.
  190.  
  191. int is_first_in_objlist(OBJECT **objlist, OBJECT *obj)
  192.         Returns non-zero if obj is the first entry in the given list.
  193.  
  194. int is_last_in_objlist(OBJECT **objlist, OBJECT *obj)
  195.         Returns non-zero if obj is the last entry in the given list.
  196.  
  197. SECTION C -- VIEWS
  198.  
  199. In addition to an OBJLIST, the rendering routines need to know about your
  200. current viewpoint; the VIEW structure contains this information.  It has
  201. three fields (ex, ey, ez) that define the current location of your "eye"
  202. or "camera" in world coordinates, and another three (pan, tilt and roll)
  203. that define the "camera's" rotation about the Y (vertical) axis, X
  204. (horizontal) axis, and Z (forward) axis respectively.
  205.  
  206. The VIEW also has near/far clipping information in the the hither and yon
  207. fields (in world coordinates).
  208.  
  209. (A note about coordinates: X is positive to the right, Y is positive up and
  210. Z is positive away from you).
  211.  
  212. There is also a zoom factor, which works like the zoom on a camera.
  213.  
  214. The angles and zoom factor are all stored as 32-bit (long) integers, but
  215. are best thought of as floating point numbers multiplied by 65536L.  This
  216. is referred to in this document as "16.16" format (16 bits of integer,
  217. 16 bits of fraction).
  218.  
  219. A VIEW also has information about what area on the screen should be used to
  220. present the scene; these left, right, top and bottom values are in absolute
  221. screen coordinates.  There is also an "aspect ratio" which determines the
  222. relative size of a non-square pixel.
  223.  
  224. The world-space coordinates of a single light source are stored in the lx,ly
  225. an lz fields.
  226.  
  227. There is also a "flags" field whose bottom bit is set if the objects should
  228. all be drawn in wire-frame mode rather than as filled polygons.  Because no
  229. explicit edge information is stored in the OBJECT data structures, wireframing
  230. is actually slower than filled-polys since each edges winds up getting drawn
  231. twice.
  232.  
  233. The next two bits (called HIDE_HIGHLIGHTED and HIDE_UNHIGHLIGHTED) determine
  234. whether highlighted (and/or unhighlighted) objects should be invisible.
  235.  
  236. There is now a pair of values (x_offset and yoffset) that effectively shift
  237. the screen center by a given amount (number of pixels), and an orientation
  238. field whose bottom bit (if set) indicates we should flip around the X axis,
  239. and whose next higher bit (if set) indicates we should flip around the Y
  240. axis.  There's also a viewpoint transform matrix.
  241.  
  242. Finally, there's a 200 byte "work area" associated with each VIEW.
  243.  
  244. void compute_view_factors(VIEW *v)
  245.    This function has been replaced by initialize_screen_factors()
  246.    and fast_view_factors(), but can still be used since it just calls
  247.    those two routines.
  248.    
  249. void initialize_screen_factors(VIEW *v)
  250.    Computes the screen factors and sets them into the given VIEW struct.
  251.    Should be called once initially, and again whenever the the zoom,
  252.    x_offsets, y_offset or orientation have changed.
  253.  
  254. void fast_view_factors(VIEW *v)
  255.    Should be called whenever the viewpoint changes.
  256.  
  257. In addition to all this, there's a global struct called Screeninfo that
  258. has the minimum and maximum X and Y values, the number of available colors,
  259. the number of pages, and the screen coordinates of the screen "center".
  260.  
  261. SECTION D -- MATRICES
  262.  
  263. A matrix is a 4 by 3 array of long (32-bit) integers.  It can best be thought
  264. of as an upper 3x3 matrix representing rotations, and 3-element bottom row
  265. vector representing translation.  A matrix is used to transform a point or
  266. an object.
  267.  
  268. void make_matrix(MATRIX m, long rx, long ry, long rz, long tx, long ty, long tz)
  269.    Fills in a matrix with the appropriate values for rotation and translation.
  270.    The rx, ry and rz values are the rotations around the three axes; these
  271.    values are all in 16.16 format (i.e. a 16-bit integer part and a 16-bit
  272.    fractional part) and are expressed in degrees.  To convert from degrees in
  273.    floating-point to this format, just multiply by 65536L.  The translation
  274.    values tx, ty and tz are all in 32-bit "world" units.
  275.  
  276. void matrix_mult(MATRIX a, MATRIX b, MATRIX c)
  277.    Does a pseudo-matrix-multiply.  The 'a' matrix is multiplied by the 'b'
  278.    matrix and the result is stored in the 'c' matrix.  Note that this is not
  279.    a real matrix multiply; only the top 3x3 matrix is affected.  You must deal
  280.    with the bottom 3-element vector separately.
  281.  
  282. void matrix_point(MATRIX m, long *xp, long *yp, long *zp)
  283.    Applies the given matrix to a point given the addresses of its x,y,z values.
  284.  
  285. void apply_matrix(OBJECT *obj, MATRIX m)
  286.    Applies the given matrix to all the vertices in the given object,
  287.    generating new world coordinates from the object coordinates.
  288.  
  289. void matrix_transpose(MATRIX a, MATRIX b)
  290.    Transposes the matrix 'a' into the matrix 'b' (exchanges rows with columns).
  291.  
  292. void inverse_matrix(MATRIX a, MATRIX b)
  293.    Finds the pseudo-inverse of 'a' and stores it in 'b'.  This is not a real
  294.    inverse; it only works for matrices in which the top 3x3 is a rotation
  295.    submatrix and the bottom row is a translation vector.
  296.  
  297. void identity(MATRIX m)
  298.    Sets the given matrix up as the identity matrix.
  299.  
  300. void matrix_copy(MATRIX src, MATRIX dst)
  301.    Copies the given matrix src to the given matrix dst.
  302.  
  303. void matrix_rot_copy(MATRIX src, MATRIX dst)
  304.    Similar to matrix_copy, but zeroes out the last row of the result.
  305.    Probably does not need to be called directly.
  306.  
  307. long m_mult(long a, long b)
  308.    Multiples two matrix elements together and returns the result.  Probably
  309.    does not need to be called directly.
  310.  
  311. long isine(long angle)
  312.    Returns the sine of the angle in internal format; the angle is in degrees,
  313.    in 16.16 format.  Probably does not need to be called directly.
  314.  
  315. long icosine(long angle)
  316.    Returns the cosine of the angle in internal format; the angle is in degrees,
  317.    in 16.16 format.  Probably does not need to be called directly.
  318.  
  319. SECTION E -- SEGMENTS
  320.  
  321. A segment is a piece of an articulated (multi-jointed) figure.  Each segment
  322. has a parent segment; the parent the "root" segment is NULL.  Each segment
  323. has a linked list of children, and each segment has a 'sibling' which
  324. is the next segment in the parent's linked list of children.
  325.  
  326. Each segment also has several values associated with it, including the
  327. position and orientation of the segment relative to its parent (or relative
  328. to the world coordinate system, for the root object) as well as a name and
  329. a "representation" which might, for example, be a pointer to an OBJECT.
  330.  
  331. SEGMENT *new_seg(SEGMENT *parent)
  332.       Creates a new segment, with the given segment as its parent.  If the
  333.       'parent' parameter is NULL, this is a root object.
  334.  
  335. void seg_setrep(SEGMENT *s, void *rep)
  336.       Sets the 'representation' field of the given segment to the given value.
  337.   
  338. void *seg_getrep(SEGMENT *s)
  339.       Returns the value of the 'representation' field of the given segment.
  340.  
  341. void seg_getposition(SEGMENT *s, long *x, long *y, long *z, long *rx,
  342.   long *ry, long *rz)
  343.       Stores the current position of the given segment (relative to its parent)
  344.       in *x, *y and *z; also stores its orientation (in 16.16 format) in *rx,
  345.       *ry and *rz.
  346.  
  347. char *seg_getname(SEGMENT *s)
  348.       Returns the name of the given segment.
  349.  
  350. void set_setname(SEGMENT *s, char *name)
  351.       Sets the name of the given segment to the given value; a copy is made.
  352.  
  353. void rel_move_segment(SEGMENT *obj, long x, long y, long z)
  354.       Performs a relative move of the given segment; x, y and z are the amounts
  355.       to move the segment along each of the three axes.  After calling this
  356.       routine, you must at some point call update_segment().
  357.  
  358. void abs_move_segment(SEGMENT *obj, long x, long y, long z)
  359.       Performs an absolute move of the given segment; x, y and z are the new
  360.       to move the segment along each of the three axes.  After calling this
  361.       routine, you must at some point call update_segment().
  362.  
  363. void rel_rot_segment(SEGMENT *seg, long rx, long ry, long rz)
  364.       Performs a relative rotation of the given segment; x, y and z are the
  365.       angles to rotate the segment along each of the three axes (in 16.16
  366.       format).  After calling this routine, you must at some point call
  367.       update_segment().
  368.  
  369. void abs_rot_segment(SEGMENT *seg, long rx, long ry, long rz)
  370.       Performs an absolute rotation of the given segment; x, y and z are the
  371.       angles to rotate the segment to along each of the three axes (in 16.16
  372.       format).  After calling this routine, you must at some point call
  373.       update_segment().
  374.  
  375. void update_segment(SEGMENT *s)
  376.       Takes the current position and orientation and uses it (and similar
  377.       information from the parent segment, and its parents, and so on) to
  378.       transform the segment's representation.
  379.  
  380. void full_update_segment(SEGMENT *s)
  381.       Similar to update_segment, but explicitly recomputes the matrices
  382.       at each node even if it's not needed.  You should not need to use
  383.       this function.
  384.  
  385. SEGMENT *find_root_segment(SEGMENT *s)
  386.       Walks up the tree from the given segment and finds the root segment for
  387.       the figure of which the segment is a part.
  388.  
  389. SEGMENT *parent_segment(SEGMENT *s)
  390.       Returns the parent of the given segment.
  391.  
  392. SEGMENT *child_segment(SEGMENT *s)
  393.       Returns the child of the given segment.
  394.  
  395. SEGMENT *sibling_segment(SEGMENT *s)
  396.       Returns the sibling of the given segment.
  397.  
  398. SEGMENT *copy_segment(SEGMENT *s, long dx, long dy, long dz,
  399.   void *(*copyrep_fn)())
  400.       Makes a copy of the given segment, displaced from the original by
  401.       dx,dy,dz, and uses the given function (if not NULL) to make a copy
  402.       of the original segment's representation and set it as the
  403.       representation of the copy.  A pointer to the new segment is returned.
  404.  
  405. void delete_segment(SEGMENT *s, void (*delrep_fn)())
  406.       Deletes the given segment and frees the memory associated with it; calls
  407.       the given function (if not NULL) to delete any representation associated
  408.       with the given segment.
  409.  
  410. void attach_segment(SEGMENT *s, SEGMENT *to)
  411.       Attaches the given segment to the given parent ('to'), making it a child
  412.       of that segment.
  413.  
  414. void detach_segment(SEGMENT *s)
  415.       Detaches the given segment from its parent, and makes it an independent
  416.       segment with no parent.  Its children remain attached to it, and other
  417.       siblings are unaffected (i.e. they still descend from the same parent
  418.       that has 'disowned' the given segment).
  419.  
  420. void seg_set_load_info(SEGMENT *s, char *filename, float sx, float sy,
  421.   float sz, long tx, long ty, long tz)
  422.       Stores the information about the scaling and translation of a loaded
  423.       representation into the SEGMENT struct; this is so we can get it back
  424.       later when it comes time to write the segment information back out to
  425.       a file again.
  426.  
  427. char *seg_get_load_info(SEGMENT *s, float *sx, float *sy, float *sz, long *tx,
  428.   long *ty, long *tz)
  429.       Retrieves the scaling and translation of a loaded representation from the
  430.       SEGMENT struct, so we can write it out to a file.
  431.  
  432. unsigned get_seg_limits(SEGMENT *s, long lims[12])
  433.       Retrieves the current segment limits and stores them in the 12 elements
  434.       of lims[].  The first two values are the minimum and maximum X
  435.       translation values, the next two are the minimum and maximum Y
  436.       translation values, and the next two are the minimum and maximum
  437.       Z translation values.  The last six are the corresponding rotational
  438.       limits (minrx, maxrx...) multiplied by 65536L.  The return value of
  439.       the function is a bitmask, the low-order bit indicating that the
  440.       minimum X value is relevant, the next higher bit indicating that
  441.       the maximum X value is relevant, and so on.  The file rend386.h
  442.       contains values like LIM_MINTX and LIM_MAXTY, so you don't have
  443.       to figure out the bits by hand.
  444.  
  445. unsigned set_seg_limits(SEGMENT *s, long lims[12], unsigned which)
  446.       Sets the current segment limits from the 12 values in lims[].  The
  447.       values are as for get_seg_limits().  The "which" parameter is a
  448.       bitmask indicating which values are to be altered by the function.
  449.       The function returns the new (updated) bitmask indicating which
  450.       values have now been set.
  451.  
  452. MATRIX *get_seg_matrix(SEGMENT *s)
  453.       Returns a pointer to the matrix associated with the given segment.
  454.  
  455. SEGMENT *find_segment_by_name(SEGMENT *s, char *name)
  456.       Returns a pointer to the segment (descended from the given segment)
  457.       whose name matches the given name.  If none is found, NULL is returned.
  458.  
  459. SECTION F -- COLORS
  460.  
  461. Four integers are defined in color16.c or color256.c; they are as follows:
  462.  
  463.   screen_clear_color -- the color to which the screen should be cleared
  464.   wireframe_color    -- the color in which to draw wireframe outlines
  465.   highlight_color    -- the color in which to highlight (outline) objects
  466.   highest_color      -- the highest color available in this mode (15 or 255)
  467.  
  468. They can be changed in the appropriate colors file to whatever values you
  469. choose.
  470.  
  471. Color-related routines are as follows:
  472.  
  473. set_colors()
  474.       Sets up (initializes) the palette.
  475.  
  476. reset_colors()
  477.       Does nothing, but could eventually restore old palette.
  478.  
  479. void read_palette(char *buffer)
  480.       Stores the current palette into the given buffer; the buffer must have
  481.       room for either 16 or 256 three-byte entries.
  482.  
  483. int user_poly_color(POLY *p, int pcolor, long maxz)
  484.       Does the mapping of user-specified color values into whatever format
  485.       gets passed to lower-level drawing routines; this is where cosine
  486.       lighting is done, for example.  The maxz specifies the polygon depth
  487.       (so you can do distance-based shading).
  488.  
  489. These routines may be changed at will, but bear in mind that this may make
  490. color usage incompatable with data files generated elsewhere.
  491.  
  492. SECTION G -- RENDERING ROUTINES
  493.  
  494. These routines are the main interface to the renderer.
  495.  
  496. void setup_render()
  497.       Sets up the internal data structures used by the renderer; should be
  498.       called before doing any other calls to any of the rend386 library
  499.       routines.
  500.  
  501. void reset_render()
  502.       Frees memory allocated for internal data structures used by the renderer;
  503.       should be called before exiting.
  504.  
  505. void render(OBJLIST *objlist, VIEW *view)
  506.       Renders all the objects in the given objlist from the given viewpoint,
  507.       writing to the current page (see set_drawpage()).
  508.  
  509. This next routine can be called by the user part of the renderer code.
  510.  
  511. int poly_cosine(void *poly)
  512.       Given a pointer to a polygon, returns the cosine of the angle between
  513.       the current light source and the polygon's surface normal; the value
  514.       returned is actually the cosine times 128.
  515.  
  516. SECTION H -- ROUTINES CALLED BY THE RENDERER
  517.  
  518. These routines are provided by the user (source in render.c); you can implement
  519. your own "back end" to the renderer just by rewriting these routines.
  520.  
  521. void user_setup_blitter()
  522.       Sets up the blitter.
  523.  
  524. void user_reset_blitter()
  525.       Resets the blitter.
  526.  
  527. void user_box(int x1, int y1, int x2, int y2, int color)
  528.       Draws a box with top left corner (x1,y1) and bottom right corner (x2,y2)
  529.       filled in the given color.
  530.  
  531. void user_text(int x, int y, int color, char *string)
  532.       Displays a string at (x,y) in the given color.
  533.  
  534. void user_render_poly(int number, int *coords, int color, long MAXZ)
  535.       Similar to ppoly, but at a higher level; lets you intercept calls and
  536.       add features.  See render.c for details.  The maxz values species the
  537.       polygon depth, so you can make distance-based polygon rendering
  538.       decisions.  NOTE THAT THIS FUNCTION HAS CHANGED ITS DEFINITION SINCE
  539.       VERSION 2.02 OF THIS SPECIFICATION!!!  We apologize for any
  540.       inconvenience.
  541.  
  542. There is also a global flag, an integer called 'wireframe', which, if non-zero,
  543. will cause all objects to be rendered in wireframe mode.  Note that this is
  544. in general slower than actual filled-polygon rendering, since the absence of
  545. explicit edge information forces each edge to be drawn twice.
  546.  
  547. SECTION I -- MISCELLANEOUS ROUTINES
  548.  
  549. OBJECT *where_screen_pt(int *pol, int *vert, int x, int y)
  550.       Given the x, y location of a point on the screen this routine returns a
  551.       pointer to the object that point is on; if pol is not NULL, it is
  552.       set to be the index in the object of the polygon the cursor is on, and
  553.       if vert is not NULL, it is set to the index of the vertex in the object
  554.       that is nearest to the given point.
  555.  
  556. long where_pt(OBJLIST objlist, long x, long y, long z, OBJECT **obj, int *vert)
  557.       Finds which object (if any) the point (x,y,z) is contained within, and
  558.       sets *obj to point to that object.  Also sets *vert to be the index of
  559.       the vertex on that object which is closest to (x,y,z) and returns the
  560.       distance from (x,y,z) to that vertex.   THIS ROUTINE HAS NOT BEEN
  561.       EXTENSIVELY TESTED!  Caveat programmer.
  562.  
  563. SECTION J -- LOWER-LEVEL GRAPHICS ROUTINES
  564.  
  565. enter_graphics()
  566.       Enter graphics mode.
  567.  
  568. exit_graphics()
  569.        Exit graphics mode.
  570.  
  571. void clear_display(int page)
  572.        Clear the given display page.
  573.  
  574. int set_drawpage(int page)
  575.        Make the given page the 'active' one for drawing.
  576.  
  577. int set_vidpage(int page, int wait)
  578.        Make the given page the 'visible' one.
  579.  
  580. void vgabox(int left, int top, int right, int bottom, int color)
  581.        Draw a box on the display at the given location in the given color.
  582.        No clipping is done!
  583.  
  584. void vgaline(int left, int top, int right, int bottom, int color)
  585.        Draw a line on the display at the given location in the given color.
  586.        No clipping is done!
  587.  
  588. SECTION K -- MOUSE ROUTINES
  589.  
  590. These routines all go through the mouse driver for reading the mouse position,
  591. but draw their own cursor (in order to support mode Y graphics).
  592.  
  593. int mouse_init()
  594.         Initializes the mouse, returns non-zero if one is present.
  595.  
  596. void mouse_deinit()
  597.         De-initializes the mouse.
  598.  
  599. int mouse_read(int *x, int *y, unsigned *buttons)
  600.         Reads the current screen position of the mouse into *x and *y, and the
  601.         current button state into *buttons; returns non-zero if the mouse or
  602.         its buttons have changed since the last call.
  603.  
  604. int mouse_hide()
  605.         Hides the mouse and decrements the mouse flag.
  606.  
  607. void mouse_show(int page)
  608.         Increments the mouse flag, and displays the cursor if the resulting
  609.         value is zero.
  610.  
  611. SECTION L -- JOYSTICK ROUTINES
  612.  
  613. The package provides support for reading a joystick.  The following struct
  614. describes the information associated with a joystick port:
  615.  
  616. typedef struct { 
  617.     int x, y, buttons;
  618.     int cenx, ceny;
  619.     int xrange, yrange;
  620.     long scale;
  621.     int port;  /* port number, 0 or 1; -1 means 'unused' */
  622.     } joystick_data;
  623.  
  624. The x, y and buttons fields are the values read from the joystick.  The
  625. cenx and ceny values are the values of x and y that are read when the joystick
  626. is centered; the values the application program sees are relative to these
  627. center values, so (0,0) is a centered stick.
  628.  
  629. The xrange and yrange values are the maximum values for x and y; the scale
  630. factor is the ratio of movement on the screen to movement of the joystick.
  631.  
  632. The value the user sees after a call to joystick_read() is, in the case of
  633. x, ((x_as_read - cenx) * scale)/xrange.
  634.  
  635. The port value specifies which of the two possible joysticks this structure
  636. corresponds to.
  637.  
  638. int joystick_check()
  639.        Checks for the presence of one or two joysticks; the returned value has
  640.        the low-order bit set if joystick 1 is present, and the next higher bit
  641.        set if joystick 2 is present.
  642.  
  643. void joystick_init(joystick_data *joy, int port)
  644.        Initializes the joystick on the given port (0 or 1)
  645.  
  646. void joystick_setscale(joystick_data *joy, int value)
  647.        Sets the scale factor for the given joystick
  648.  
  649. void joystick_scale(joystick_data *joy, int dir)
  650.        Used for joystick calibration; should be called with dir = 0 and joystick
  651.        forward and to the left, then again with dir = 1 and joystick backward and
  652.        to the right.  This sets the xrange and yrange values for you.
  653.  
  654. int joystick_read(joystick_data *joystick)
  655.        Reads the current values of the specified joystick.
  656.  
  657. void joystick_quit()
  658.        De-initializes joystick processing (current does nothing)
  659.  
  660. SECTION M -- POINTER ROUTINES
  661.  
  662. Primitive support is provided for 3-dimensional pointing devices.  The file
  663. pointer.c contains a set of routines that map the movement of a standard
  664. mouse into three-space; horizontal is X, vertical is Y, and vertical with the
  665. right-hand button down is Z.  If you have a "real" 3D pointing device (e.g.
  666. PowerGlove) you can rewrite the routines in pointer.c to make use of it.
  667.  
  668. The following structure is used to return information about the 3D pointer:
  669.  
  670. typedef struct {
  671.     long x, y, z;          /* location in world coordinates */
  672.     long pan, tilt, roll;  /* orientation around x, y, z */
  673.     unsigned buttons;      /* 16 bits */
  674.     unsigned gesture;      /* for future expansion */
  675.     int port;              /* in case we need this */
  676.     long sx, sy, sz;       /* scaling factors */
  677.     int flex[16];          /* up to 16 words of flexion information */
  678.     } POINTER;
  679.  
  680. The x, y and z values are the location of the pointer in world coordinates.
  681. The pan, tilt and roll are the rotation of the pointer in 16.16 format.
  682. The buttons represent up to 16 buttons, each of which is down or up; in the
  683. case of the powerglove, this may correspond to one byte of finger information
  684. and one byte of button information (for example).
  685.  
  686. The port value is used in case multiple 3D pointing devices are available.
  687.  
  688. The scaling values are used to alter the movement of the pointer relative
  689. to that of the pointing device.
  690.  
  691. The 16 words of flexion information are provided for devices that provide
  692. more detailed information about joint angles; the gesture field is provided
  693. for those systems that support gesture recognition.
  694.  
  695. pointer_init(int port, POINTER *pointer)
  696.       Initializes the pointing device on the given port; returns non-zero if
  697.       a device is found, zero otherwise.
  698.  
  699. pointer_read(POINTER *pointer)
  700.       Reads the given pointer, updating the fields in the given struct, and
  701.       returning non-zero if the pointer has changed state (location,
  702.       orientation or buttons) since the last call to pointer_read().
  703.  
  704. void pointer_scale(POINTER *pointer, long sx, long sy, long sz)
  705.       Sets the scaling for the pointer x, y, and z values.
  706.  
  707. void pointer_quit(POINTER *pointer)
  708.       De-initializes the given pointing device.
  709.  
  710. void pointer_move(POINTER *pointer, long x, long y, long z)
  711.       Sets the current position of the pointer in world coordinates; all
  712.       subsequent movements of the pointing device will be relative to this
  713.       position.
  714.  
  715. SECTION N -- USER-INTERFACE ROUTINES
  716.  
  717. These routines allow you to provide a simple user interface.
  718.  
  719. void neatbox(int w, int h, int *x, int *y)
  720.         Displays a neat-looking box of height h and width w, centered on the
  721.         screen.  The *x and *y values are set to the computed top-left corner
  722.         of the box.
  723.  
  724. void poptext(char *text[])
  725.         Pops up text box on the screen; the 'text' parameter is an array of
  726.         strings, the last of which is NULL.
  727.  
  728. void popmsg(char *msg)
  729.         Pops up a one-line message in a box centered on the screen
  730.  
  731. unsigned askfor(char *prompt, char *buff, int n)
  732.         Prompts the user to enter a string; buff must contain room for up to n
  733.         characters plus a null byte to terminate the string.
  734.  
  735. SECTION O -- PLG FILE I/O ROUTINES
  736.  
  737. The ".plg" file format is described in plg.doc; it is not tightly coupled to
  738. the rest of the renderer software.
  739.  
  740. OBJECT *load_plg(FILE *in)
  741.       Loads a .plg file and returns a pointer to the newly-created OBJECT.
  742.       The global variable load_err will be set to a non-zero value if there
  743.       was a problem loading the file.  As the file is loaded, it is first
  744.       scaled by the current scaling factor and then shifted by the current
  745.       x,y,z offset.
  746.  
  747. void set_loadplg_offset(long x, long y, long z)
  748.       Specifies the x,y,z offset to use; see figure.doc for details.
  749.     
  750. void set_loadplg_scale(float x, float y, float z)
  751.       Specifies the x,y,z scaling to use; see figure.doc for details.
  752.  
  753. save_plg(OBJECT *obj, FILE *out)
  754.       Saves the given object as a .plg file.
  755.  
  756. void set_loadplg_depthsort(type)
  757.       Sets the depth-sorting type to a particular value (see description of
  758.       depth sorting earlier in this document for details).
  759.  
  760. void set_loadplg_colormap(unsigned *map, int msize)
  761.       If the top bit of a color value in a .plg file is set, the bottom
  762.       15 bits are taken to be an index into a "map" that specifies the
  763.       actual color value to be used.  The map consists of msize values,
  764.       each of which is an unsigned 16-bit number.
  765.  
  766. In addition, a global int variable called load_err is set to a non-zero
  767. value if an error was encountered while loading a .plg file; see the code in
  768. plg.c for details.
  769.  
  770. SECTION P -- FIG FILE I/O ROUTINES
  771.  
  772. A figure file consists of a set of segments.  See figure.doc for details.
  773. The format of a figure file is not tightly coupled to the rest of the
  774. renderer.
  775.  
  776. SEGMENT *readseg(FILE *in, SEGMENT *parent)
  777.      Allocates a new segment, with the given parent, and reads a segment
  778.      description into that segment.  If the file contains nested segments,
  779.      readseg will recursively call itself to load them.  See figure.doc for
  780.      more information.  The global integer variable readseg_err will be set
  781.      to a non-zero value if an error was encountered during loading.
  782.  
  783. void set_readseg_objlist(OBJLIST *objlist)
  784.      Sets the given object list as the one to add newly-loaded representations
  785.      to.
  786.  
  787. void set_readseg_seglist(SEGMENT **seglist, int maxsegs)
  788.      Segments in .FIG files now have an optional "segnum" attribute that
  789.      associates a simple integer with a the segment.  This allows you to
  790.      subsequently refer to segments by number.  The given seglist is an
  791.      array of pointers to segments, which will get filled in as segments
  792.      get loaded.  The value maxsegs specifies the number of slots in
  793.      the seglist.  Note that you can have as many seglists as you like,
  794.      possibly even one for each figure.
  795.  
  796. writeseg(FILE *out, SEGMENT *s, int level)
  797.      Writes the given segment out to a file; 'level' is used to provide
  798.      levels of indentation, since writeseg calls itself recursively.  In
  799.      general, root segments should be written out with level = 0.
  800.  
  801. In addition, a global int variable called readseg_err is set to a non-zero
  802. value if an error was encountered while loading a .fig file; see the code in
  803. segio.c for details.
  804.  
  805. SECTION Q -- PCX FILE I/O ROUTINES
  806.  
  807. These routines are only available in 256 color mode, and allow you to read
  808. and write .PCX files (PC-Paintbrush format).
  809.  
  810. load_pcx(FILE *in, int page)
  811.        Load a 320x200x256 .PCX image from the given file onto the given
  812.        display page.
  813.  
  814. int save_pcx(FILE *out, int page)
  815.        Save a 320x200x256 .PCX image into the given file from the given
  816.        display page.
  817.  
  818. SECTION R -- STEREOSCOPIC RENDERING
  819.  
  820. The rend386 package now supports stereoscopic rendering.  The structure
  821. STEREO is used to store information about the stereo environment.
  822.  
  823. The fields in this structure are:
  824.     phys_screen_dist  - the distance in mm from the eye to the screen
  825.     phys_screen_width - the viewport width on the screen in mm
  826.     pixel_width       - the viewport width in pixels
  827.     phys_eye_spacing  - the physical spacing between the eyes, in mm
  828.     world_scaling     - world units per physical mm
  829.     phys_convergence  - the convergence distance in mm (usually the same
  830.                         as phys_screen_dist)
  831.  
  832. All units are stored as long integers.
  833.  
  834. The following routines support stereoscopic rendering:
  835.  
  836. void make_stereo_view(VIEW *orig, VIEW *new, STEREO *s, int eye)
  837.     Creates a new VIEW from the original, using the information in s.
  838.     The 'eye' parameter should be 1 for the left eye or two for the right
  839.     eye.  This function would get called twice per rendering, once with
  840.     eye == 1 and once with eye == 2.
  841.  
  842.       The correct sequence to do things when updating the screen is:
  843.            fast_view_factors(&v);
  844.            make_stereo_view(&v, &left, st, 1);
  845.            render(objlist, &left);
  846.            make_stereo_view(&v, &right, st, 2);
  847.            render(objlist, &right)
  848.  
  849.  
  850. void mirr_stereo_view(VIEW *orig, VIEW *new, STEREO *s, int eye)
  851.      Same as make_stereo_view(), but for use with mirror viewing instead
  852.      of Sega glasses.
  853.  
  854. void update_stereo_view(VIEW *v, STEREO *s, int eye)
  855.      If only the view has changed, you can call udpate_stereo_view() for
  856.      each eye.  In other words, update_stereo_view(&left, st, 1) and
  857.      update_stereo_view(&right, st, 2).
  858.  
  859. See the routine refresh_display() in demo3.c for an example of how all this
  860. works.
  861.  
  862. SECTION S -- SUPPORT FOR THE SEGA 3D GLASSES AND NINTENDO POWERGLOVE
  863.  
  864. The Sega 3D glasses are now supported by rend386.  See the file sega.txt for
  865. details on how to build an interface for the Sega glasses that allows them to
  866. be connected to a serial port.
  867.  
  868. The Nintendo Powerglove is now supported by rend386.  See the article in the
  869. June 1990 Byte magazine for details on constructing a cable that allows the
  870. glove to be connected to a parallel port.
  871.  
  872. In order to use the Sega glasses or the Nintendo Powerglove, you must call
  873. the following routine:
  874.  
  875. void init_SG_interrupt(void (*sega_switcher), void (*glove_handler), int tc)
  876.     Installs interrupt support for the Sega glasses and the Nintendo glove.
  877.     The sega_switcher() routine will be called just before the vertical
  878.     retrace triggers, and the glove_handler() routine will be called at
  879.     least once per screen refresh.  If either routine is NULL, then that
  880.     routine will not be called.  The tc value indicates the interval (in
  881.     units of 1.19 microseconds) for polling the glove; 6500 is a good
  882.     value to use if the sega_switcher is also being used.
  883.  
  884. Two routines are provided which may be passed as parameters to the
  885. init_SG_interrupt() routine: switch_sega() and glove_int_handler().
  886.  
  887. The switch_sega() routine switches the sega glasses from left eye to right
  888. eye or vice-versa, and swaps the screen as well.  The global variable
  889. left_page is the number of the screen page that contains the left-eye image,
  890. and right_page is the number of the screen page that contains the right-eye
  891. image.  In Mode X, four pages are available altogether, so you can have
  892. an "active" left-right pair and a "visual" left-right pair; see the code
  893. for refresh_display in demo3.c for details on how this works.
  894.  
  895. The global variable rs232_port_adr contains the address of the serial port
  896. that should be used for controlling the glasses.
  897.     
  898. The routine sega_off() can be used to make both lenses on the Sega glasses
  899. transparent; it should be called before exiting to avoid damaging the glasses.
  900.  
  901. The following struct contains data from the Powerglove:
  902.  
  903. typedef struct {
  904.     signed char x, y, z, rot, fingers, keys, gstat1, gstat2, rxflags;
  905.     unsigned int nmissed;
  906.     } glove_data;
  907.  
  908. The x, y, and z values are the location of the glove in three-space; the
  909. rot value is the rotation position (0 to 12).  The fingers are a one-byte
  910. bitmap, two bits for each of the thumb and three fingers (pinky not included).
  911. The keys value indicates which keys are down on the wrist control panel.
  912.  
  913. The following routines can be used to interface to the Powerglove:
  914.  
  915. void glove_init(int gdeg)
  916.    Sets up the glove and enters hi-res mode.  If gdeg is non-zero, deglitching
  917.    is enabled.
  918.  
  919. int glove_ready()
  920.    Returns 0 if the glove is not ready, 1 if data is ready, 2 if data is ready
  921.    and the rxflags are valid.
  922.  
  923. int glove_read(glove_data *gdata)
  924.    Reads the glove data into the given struct, and returns non-zero if the
  925.    data has changed since the last time the routine was called.
  926.  
  927. Note that there is still considerable inherent glitching in the glove due
  928. to noise, reflections and so forth.
  929.  
  930. THE FUTURE:
  931.  
  932. This rendering package is intended to be the foundation for a wide range
  933. of applications.
  934.  
  935. For further information about the package, feel free to contact us:
  936.  
  937.     Bernie Roehl (broehl@sunee.waterloo.edu)
  938.     Dave Stampe (dstampe@sunee.waterloo.edu)
  939.  
  940. Note that at some point in the future, sunee.waterloo.edu will become
  941. sunee.uwaterloo.ca (the ".ca" stands for CAnada, not CAlifornia!)
  942.  
  943. The major contribution others can make to the project at this stage is
  944. to write converters from other polygon formats to OFF.  In particular,
  945. a DXF to OFF converter would let us create objects with a CAD package.
  946.  
  947. OFF is a reasonably good, open format that encodes author/copyright
  948. information along with geometry and colors.  While it's a bit of a
  949. nuisance to parse, it's very easy to generate.
  950.  
  951. Two of our data files were converted from OFF files using off2plg: the bishop
  952. and the banana.  Below is the author/copyright information from their .aoff
  953. files:
  954.  
  955. name        bishop8
  956. description    chess piece - bishop
  957. author        Randy Brown, brown@cs.unc.edu
  958. copyright    (c) Randy Brown, OK to distribute if copyright/author appears 
  959.  
  960. name        banana
  961. description    Banana made on Frank Crow's U. Utah surface design system
  962. copyright    (c) Ohio State Univ. - ok to distribute if copyright appears
  963.  
  964. That's it.  Please direct any questions to broehl@sunee.waterloo.edu or
  965. dstamp@serv1.waterloo.edu, or join the mailing list.  To join the list,
  966. send mail to rend386-request@sunee.uwaterloo.ca (the list itself is just
  967. rend386@sunee.uwaterloo.ca).
  968.